--
-- DE2 (Cyclone-II) Entity for Interactive Project Game
-- Authors:
--      Abdulhamid Ghandour
--      Thomas John
--      Jaime Peretzman
--      Bharadwaj Vellore
--
-- Desc:
--
-- From an original by Terasic Technology, Inc.
-- (DE2_TOP.v, part of the DE2 system board CD supplied by Altera)
--

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity niostop is

  port (
    -- Clocks
    
    CLOCK_27,                                      -- 27 MHz
    CLOCK_50,                                      -- 50 MHz
    EXT_CLOCK : in std_logic;                      -- External Clock

    -- Buttons and switches
    
    KEY : in std_logic_vector(3 downto 0);         -- Push buttons
    SW : in std_logic_vector(17 downto 0);         -- DPDT switches

    -- LED displays

    HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7 -- 7-segment displays
       : out std_logic_vector(6 downto 0);         -- (active low)
    LEDG : out std_logic_vector(8 downto 0);       -- Green LEDs (active high)
    LEDR : out unsigned(17 downto 0);      -- Red LEDs (active high)

    -- RS-232 interface

    UART_TXD : out std_logic;                      -- UART transmitter   
    UART_RXD : in std_logic;                       -- UART receiver

    -- IRDA interface

    --IRDA_TXD : out std_logic;                      -- IRDA Transmitter
    IRDA_RXD : in std_logic;                       -- IRDA Receiver

    -- SDRAM
   
    DRAM_DQ : inout std_logic_vector(15 downto 0); -- Data Bus
    DRAM_ADDR : out std_logic_vector(11 downto 0); -- Address Bus    
    DRAM_LDQM,                                     -- Low-byte Data Mask 
    DRAM_UDQM,                                     -- High-byte Data Mask
    DRAM_WE_N,                                     -- Write Enable
    DRAM_CAS_N,                                    -- Column Address Strobe
    DRAM_RAS_N,                                    -- Row Address Strobe
    DRAM_CS_N,                                     -- Chip Select
    DRAM_BA_0,                                     -- Bank Address 0
    DRAM_BA_1,                                     -- Bank Address 0
    DRAM_CLK,                                      -- Clock
    DRAM_CKE : out std_logic;                      -- Clock Enable

    -- FLASH
    
    FL_DQ : inout std_logic_vector(7 downto 0);      -- Data bus
    FL_ADDR : out std_logic_vector(21 downto 0);  -- Address bus
    FL_WE_N,                                         -- Write Enable
    FL_RST_N,                                        -- Reset
    FL_OE_N,                                         -- Output Enable
    FL_CE_N : out std_logic;                         -- Chip Enable

    -- SRAM
    
    SRAM_DQ : inout std_logic_vector(15 downto 0);         -- Data bus 16 Bits
    SRAM_ADDR : out std_logic_vector(17 downto 0);         -- Address bus 18 Bits
    SRAM_UB_N,                                     -- High-byte Data Mask 
    SRAM_LB_N,                                     -- Low-byte Data Mask 
    SRAM_WE_N,                                     -- Write Enable
    SRAM_CE_N,                                     -- Chip Enable
    SRAM_OE_N : out std_logic;                     -- Output Enable

    -- USB controller
    
    OTG_DATA : inout std_logic_vector(15 downto 0); -- Data bus
    OTG_ADDR : out std_logic_vector(1 downto 0);    -- Address
    OTG_CS_N,                                       -- Chip Select
    OTG_RD_N,                                       -- Write
    OTG_WR_N,                                       -- Read
    OTG_RST_N,                                      -- Reset
    OTG_FSPEED,                     -- USB Full Speed, 0 = Enable, Z = Disable
    OTG_LSPEED : out std_logic;     -- USB Low Speed, 0 = Enable, Z = Disable
    OTG_INT0,                                       -- Interrupt 0
    OTG_INT1,                                       -- Interrupt 1
    OTG_DREQ0,                                      -- DMA Request 0
    OTG_DREQ1 : in std_logic;                       -- DMA Request 1   
    OTG_DACK0_N,                                    -- DMA Acknowledge 0
    OTG_DACK1_N : out std_logic;                    -- DMA Acknowledge 1

    -- 16 X 2 LCD Module
    
    LCD_ON,                     -- Power ON/OFF
    LCD_BLON,                   -- Back Light ON/OFF
    LCD_RW,                     -- Read/Write Select, 0 = Write, 1 = Read
    LCD_EN,                     -- Enable
    LCD_RS : out std_logic;     -- Command/Data Select, 0 = Command, 1 = Data
    LCD_DATA : inout std_logic_vector(7 downto 0); -- Data bus 8 bits

    -- SD card interface
    
    SD_DAT : in std_logic;      -- SD Card Data      SD pin 7 "DAT 0/DataOut"
    SD_DAT3 : out std_logic;    -- SD Card Data 3    SD pin 1 "DAT 3/nCS"
    SD_CMD : out std_logic;     -- SD Card Command   SD pin 2 "CMD/DataIn"
    SD_CLK : out std_logic;     -- SD Card Clock     SD pin 5 "CLK"

    -- USB JTAG link
    
    TDI,                        -- CPLD -> FPGA (data in)
    TCK,                        -- CPLD -> FPGA (clk)
    TCS : in std_logic;         -- CPLD -> FPGA (CS)
    TDO : out std_logic;        -- FPGA -> CPLD (data out)

    -- I2C bus
    
    I2C_SDAT : inout std_logic; -- I2C Data
    I2C_SCLK : out std_logic;   -- I2C Clock

    -- PS/2 port

    PS2_DAT,                    -- Data
    PS2_CLK : in std_logic;     -- Clock

    -- VGA output
    
    VGA_CLK,                            -- Clock
    VGA_HS,                             -- H_SYNC
    VGA_VS,                             -- V_SYNC
    VGA_BLANK,                          -- BLANK
    VGA_SYNC : out std_logic;           -- SYNC
    VGA_R,                              -- Red[9:0]
    VGA_G,                              -- Green[9:0]
    VGA_B : out std_logic_vector(9 downto 0);   -- Blue[9:0]

    --  Ethernet Interface
    
    ENET_DATA : inout unsigned(15 downto 0);    -- DATA bus 16 Bits
    ENET_CMD,           -- Command/Data Select, 0 = Command, 1 = Data
    ENET_CS_N,                                  -- Chip Select
    ENET_WR_N,                                  -- Write
    ENET_RD_N,                                  -- Read
    ENET_RST_N,                                 -- Reset
    ENET_CLK : out std_logic;                   -- Clock 25 MHz
    ENET_INT : in std_logic;                    -- Interrupt
    
    -- Audio CODEC
    
    AUD_ADCLRCK : inout std_logic;                      -- ADC LR Clock
    AUD_ADCDAT : in std_logic;                          -- ADC Data
    AUD_DACLRCK : inout std_logic;                      -- DAC LR Clock
    AUD_DACDAT : out std_logic;                         -- DAC Data
    AUD_BCLK : inout std_logic;                         -- Bit-Stream Clock
    AUD_XCK : out std_logic;                            -- Chip Clock
    
    -- Video Decoder
    
    TD_DATA : in std_logic_vector(7 downto 0);  -- Data bus 8 bits
    TD_HS,                                      -- H_SYNC
    TD_VS : in std_logic;                       -- V_SYNC
    TD_RESET : out std_logic;                   -- Reset
    
    -- General-purpose I/O
    
    GPIO_0,                                      -- GPIO Connection 0
    GPIO_1 : inout std_logic_vector(35 downto 0) -- GPIO Connection 1   
    );
  
end niostop;

architecture datapath of niostop is
  signal clk25 : std_logic := '0';
  signal reset_n : std_logic := '1';
  signal int_sclk : std_logic;
  signal int_sdat : std_logic;
  signal stop_counter : std_logic := '0';
  signal frameCount : unsigned(31 downto 0) := x"00000000";
  signal tickCount : unsigned(31 downto 0) := x"00000000";

  component de2_i2c_av_config is
  port (
    iCLK : in std_logic;
    iRST_N : in std_logic;
    I2C_SCLK : out std_logic;
    I2C_SDAT : inout std_logic
  );
  end component;

begin
  reset_n <= KEY(0);

  process (CLOCK_50)
  begin
    if rising_edge(CLOCK_50) then
      clk25 <= not clk25;
    end if;
  end process;

  niossystem: entity work.pool port map (
    clk => CLOCK_50,
    reset_n => KEY(0), 

    -- the_sram
    SRAM_ADDR_from_the_sram => SRAM_ADDR,
    SRAM_CE_N_from_the_sram => SRAM_CE_N,
    SRAM_DQ_to_and_from_the_sram => SRAM_DQ,
    SRAM_LB_N_from_the_sram => SRAM_LB_N,
    SRAM_OE_N_from_the_sram => SRAM_OE_N,
    SRAM_UB_N_from_the_sram => SRAM_UB_N,
    SRAM_WE_N_from_the_sram => SRAM_WE_N,

    -- the_vga
    VGA_BLANK_from_the_vga => VGA_BLANK,
    VGA_B_from_the_vga => VGA_B,
    VGA_CLK_from_the_vga => VGA_CLK,
    VGA_G_from_the_vga => VGA_G,
    VGA_HS_from_the_vga => VGA_HS,
    VGA_R_from_the_vga => VGA_R,
    VGA_SYNC_from_the_vga => VGA_SYNC,
    VGA_VS_from_the_vga => VGA_VS,

    -- the_vision
    frame_valid_to_the_vision => GPIO_1(13),
    line_valid_to_the_vision => GPIO_1(12),
    master_clk_from_the_vision => GPIO_1(11),
    no_detect_from_the_vision => LEDG(0),
    pixel_clk_to_the_vision => GPIO_1(10),
    pixel_data_to_the_vision(0) => GPIO_1(0),
    pixel_data_to_the_vision(1) => GPIO_1(1),
    pixel_data_to_the_vision(2) => GPIO_1(5),
    pixel_data_to_the_vision(3) => GPIO_1(3),
    pixel_data_to_the_vision(4) => GPIO_1(2),
    pixel_data_to_the_vision(5) => GPIO_1(4),
    pixel_data_to_the_vision(6) => GPIO_1(6),
    pixel_data_to_the_vision(7) => GPIO_1(7),
    pixel_data_to_the_vision(8) => GPIO_1(8),
    pixel_data_to_the_vision(9) => GPIO_1(9),
    threshold_to_the_vision => SW(9 downto 0),

    -- the_audio
    aud_adcdat_to_the_sounddriver => AUD_ADCDAT,
    aud_adclrck_from_the_sounddriver => AUD_ADCLRCK,
    aud_bclk_to_and_from_the_sounddriver => AUD_BCLK,
    aud_dacdat_from_the_sounddriver => AUD_DACDAT,
    aud_daclrck_from_the_sounddriver => AUD_DACLRCK,
    aud_xck_from_the_sounddriver => AUD_XCK,

    -- the_camera
    sclk_from_the_camera        => int_sclk,
    sdat_to_and_from_the_camera => int_sdat,
    ack_to_the_camera => GPIO_1(15)
  );

  frame_counter: process (GPIO_1(13))
  begin
    if rising_edge(GPIO_1(13)) then
      if reset_n = '0' then
        frameCount <= x"00000000";
      else
        if stop_counter = '1' then

        else
          frameCount <= frameCount + 1;
        end if;
      end if;
    end if;
  end process;

  tick_counter: process (clk25)
  begin
    if rising_edge(clk25) then
      if reset_n = '0' then
        stop_counter <= '0';
        tickCount <= x"00000000";
      else
        if stop_counter = '1' then

        else
          tickCount <= tickCount + 1;
          if(tickCount > x"05f5e100") then
            stop_counter <= '1';
          end if;
        end if;
      end if;
    end if;
  end process;

  LEDR <= frameCount(20 downto 3);

  i2c : de2_i2c_av_config port map (
    iCLK     => CLOCK_50,
    iRST_n   => '1',
    I2C_SCLK => I2C_SCLK,
    I2C_SDAT => I2C_SDAT
  );

  LEDG(2) <= int_sclk;
  LEDG(1) <= int_sdat;
  LEDG(7) <= GPIO_1(13);
  LEDG(6) <= GPIO_1(12);
  GPIO_1(14) <= int_sclk;
  GPIO_1(15) <= int_sdat;

  GPIO_0(14) <= GPIO_1(14);
  GPIO_0(15) <= GPIO_1(15);
  GPIO_0(11) <= int_sdat;

  HEX7     <= (others => '1'); -- Leftmost
  HEX3     <= (others => '1');
  HEX2     <= (others => '1');
  HEX1     <= (others => '1');
  HEX0     <= (others => '1'); -- Rightmost

  LCD_ON   <= '1';
  LCD_BLON <= '1';
  FL_RST_N <= '1';

  LCD_RW <= '1';
  LCD_EN <= '0';
  LCD_RS <= '0';
  FL_ADDR(21 downto 20) <= "00";

  SD_DAT3 <= '1';  
  SD_CMD <= '1';
  SD_CLK <= '1';

  UART_TXD <= '0';
  DRAM_ADDR <= (others => '0');
  DRAM_LDQM <= '0';
  DRAM_UDQM <= '0';
  DRAM_WE_N <= '1';
  DRAM_CAS_N <= '1';
  DRAM_RAS_N <= '1';
  DRAM_CS_N <= '1';
  DRAM_BA_0 <= '0';
  DRAM_BA_1 <= '0';
  DRAM_CLK <= '0';
  DRAM_CKE <= '0';
  FL_WE_N <= '1';
  
  FL_OE_N <= '1';
  FL_CE_N <= '1';
  OTG_ADDR <= (others => '0');
  OTG_CS_N <= '1';
  OTG_RD_N <= '1';
  OTG_RD_N <= '1';
  OTG_WR_N <= '1';
  OTG_RST_N <= '1';
  OTG_FSPEED <= '1';
  OTG_LSPEED <= '1';
  OTG_DACK0_N <= '1';
  OTG_DACK1_N <= '1';

  ENET_CMD <= '0';
  ENET_CS_N <= '1';
  ENET_WR_N <= '1';
  ENET_RD_N <= '1';
  ENET_RST_N <= '1';
  ENET_CLK <= '0';

  TDO <= '0';
  TD_RESET <= '0';

  -- Set all bidirectional ports to tri-state
  DRAM_DQ     <= (others => 'Z');
  FL_DQ       <= (others => 'Z');
  OTG_DATA    <= (others => 'Z');
  LCD_DATA    <= (others => 'Z');
  ENET_DATA   <= (others => 'Z');
end datapath;
